import { fromEvent } from 'rxjs';
import { map, takeUntil, concatAll, filter } from 'rxjs/operators';
type TEventCallback<T = MouseEvent, Res = any> = (event: T) => Res
export namespace EventHelper {
    export function drag(ele: HTMLElement) {
        const mouseDown = fromEvent<any>(ele, "mousedown")
        const mouseMove = fromEvent<any>(document, "mousemove");
        const mouseUp: any = fromEvent<any>(document, "mouseup");
        return mouseDown
        .pipe(
          map((e: any) => {
            const top = e.target.style.top.replace('px', '');
            const left = e.target.style.left.replace('px', '');
            const clickOffsetX = e.clientX - left;
            const clickOffsetY = e.clientY - top;
            return {
              x:clickOffsetX,
              y:clickOffsetY
            };
          }),
          map((postion: any) => {
            return mouseMove.pipe(
              takeUntil(mouseUp),
              map((moveEvent: MouseEvent) => {
                  return {
                    x: moveEvent.clientX - postion.x,
                    y: moveEvent.clientY - postion.y
                  }
              })
            );
          }),
          concatAll()
        );
    }
    export function move<T = any>(ele: HTMLElement, downCallback: any, upCallback: any, moveCallback: any) {
      const mouseDown = fromEvent<any>(ele, "mousedown")
      .pipe(filter((evt: MouseEvent) => {
        evt.preventDefault();
        evt.stopPropagation();
        return evt.button == 0;
      }))
      .pipe(map(evt => {
          return evt;
      }))
      const mouseMove = fromEvent<any>(document, "mousemove");
      const mouseUp: any = fromEvent<any>(document, "mouseup")
      // .pipe(map((evt) => {
      //     evt.preventDefault();
      //     evt.stopPropagation();
      //     return upCallback(evt);
      // }))
      mouseDown
      .pipe(
        map((e: any) => {
          return downCallback(e);
        }),
        map((postion: any) => {
          return mouseMove.pipe(
            takeUntil(
              mouseUp
              .pipe(map((evt: MouseEvent) => {
                evt.preventDefault();
                evt.stopPropagation();
                return upCallback(evt, postion);
              }))
            ),
            map((moveEvent: MouseEvent) => {
              moveEvent.preventDefault();
              moveEvent.stopPropagation();
              return moveCallback(postion, moveEvent);
            })
          );
        }),
        concatAll()
      ).subscribe(res => {
          // console.log(res);
          // moveCallback(res);
      });
    }
}